package controller;

public final class MonteCarloSimulation {

	public static double MonteCarloStandardOption(String CallPutFlag, double S,
			double X, double T, double r, double b, double v, int nSteps,
			int nSimulations) {
		double dt;
		double St;
		double Sum = 0;
		double Drift;
		double vSqrdt;
		int i, j, z = 1;
		java.util.Random random = new java.util.Random();

		dt = T / nSteps;
		Drift = (b - v*v / 2) * dt;
		vSqrdt = v * java.lang.Math.sqrt(dt);
		if (CallPutFlag == "c") {
			z = 1;
		} else if (CallPutFlag == "p") {
			z = -1;
		}
		for (i = 1; i <= nSimulations; i++) {
			St = S;
			for (j = 1; j <= nSteps; j++) {
				St = St
						* java.lang.Math.exp(Drift + vSqrdt
								* random.nextGaussian());
			}
			Sum = Sum + java.lang.Math.max(z * (St - X), 0);
		}
		return (java.lang.Math.exp(-r * T) * (Sum / nSimulations));
	}
	
	public static double singleSimulation(String CallPutFlag, double S,
			double X, double T, double r, double b, double v, int nSteps){
		double dt;
		double St;
		double Sum = 0;
		double Drift;
		double vSqrdt;
		int i, j, z = 1;
		java.util.Random random = new java.util.Random();

		dt = T / nSteps;
		Drift = (b - v*v / 2) * dt;
		vSqrdt = v * java.lang.Math.sqrt(dt);
		if (CallPutFlag == "c") {
			z = 1;
		} else if (CallPutFlag == "p") {
			z = -1;
		}
			St = S;
			for (j = 1; j <= nSteps; j++) {
				St = St
						* java.lang.Math.exp(Drift + vSqrdt
								* random.nextGaussian());
			}
		return (java.lang.Math.max(z * (St - X), 0));
	}
	
	public static double average(double r, double T, double Sum, int nSimulations){
		return (java.lang.Math.exp(-r * T) * (Sum / nSimulations));
	}
}
